<!DOCTYPE html> <!-- -*- html -*- -->
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1">
  <title>Transformation challenges</title>
  <link rel="shortcut icon" href="img/gatech.gif"/>

  
      <link rel="stylesheet" href="css/demo.css?vers=2759ff">
  

  <style>
      
#help-text {
    # text-align: center;
# }
.mathbox-overlays {
    pointer-events: auto;
}
#optimal {
    color: green
}
#non-optimal {
    color: yellow
}
#new_challenge_div, #picker_div, #challenge_div, #challenge_list {
    text-align: center
}

#button-table {
    margin: auto
}
#challenge_list {
    list-style: none;
    padding-left:0
}
button {
    padding: 0.5em;
    border-radius: 0;
    border: none;
    background-color: white
}
button:hover {
    background-color: LightBlue;
}
#new-challenge-btn {
    background-color: LightGreen;
}
#new-challenge-btn:hover {
    background-color: #33CC33;
}


  </style>

</head>
<body>
    

    
    
        <script src="js/demo.js?vers=77646a"></script>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


    <script type="text/javascript">
        "use strict";
        DomReady.ready(function() {

        var ortho, ref;

ortho = 10000;

window.are_matrices_equal = function(m1, m2) {
  var i, j;
  for (i = j = 0; j < 4; i = ++j) {
    if (Math.abs(window.matrix[i] - window.winning_matrix[i]) > 0.0001) {
      return false;
    }
  }
  return true;
};

window.multiply = function(m1, m2) {
  var a, b, c, d;
  a = m1[0] * m2[0] + m1[1] * m2[2];
  b = m1[0] * m2[1] + m1[1] * m2[3];
  c = m1[2] * m2[0] + m1[3] * m2[2];
  d = m1[2] * m2[1] + m1[3] * m2[3];
  return [a, b, c, d];
};

window.matrix = [1, 0, 0, 1];

window.tempmatrix = [1, 0, 0, 1];

window.updateMatrix = (function(_this) {
  return function(multiplier) {
    _this.count += 1;
    _this.matrix = _this.multiply(multiplier, _this.matrix);
    _this.hideTempImage();
    if (_this.are_matrices_equal(_this.matrix, _this.winning_matrix)) {
      return _this.announce_result();
    }
  };
})(this);

window.tempUpdateMatrix = (function(_this) {
  return function(multiplier) {
    _this.tempmatrix = _this.multiply(multiplier, _this.matrix);
    _this.mathbox.select("#temp_image").set('visible', true);
    return _this.mathbox.select("#real_image").set('visible', false);
  };
})(this);

window.hideTempImage = (function(_this) {
  return function() {
    _this.mathbox.select("#temp_image").set('visible', false);
    return _this.mathbox.select("#real_image").set('visible', true);
  };
})(this);

window.random_matrix = function(word_length) {
  var generators, i, idx, j, ref, result;
  generators = [this.matrices['shear_left'], this.matrices['shear_right'], this.matrices['shear_up'], this.matrices['shear_down'], this.matrices['reflect_x_axis']];
  result = [1, 0, 0, 1];
  for (i = j = 1, ref = word_length; 1 <= ref ? j < ref : j > ref; i = 1 <= ref ? ++j : --j) {
    idx = Math.floor(Math.random() * 5);
    result = this.multiply(result, generators[idx]);
    console.log(result);
  }
  return result;
};

window.startGame = function(challenge) {
  var id, j, len, ref, results;
  this.count = 0;
  this.matrix = challenge.starting_matrix;
  if (this.matrix === 'random') {
    this.matrix = this.random_matrix(10);
  }
  console.log(this.matrix);
  this.winning_matrix = challenge.winning_matrix;
  this.min_count = challenge.min_count;
  $("#challenge_inst").html(challenge.message);
  $("#challenge_div").show();
  $("#picker_div").hide();
  $("#new_challenge_div").show();
  $("#button-table").find("tr").hide();
  ref = challenge.transformations;
  results = [];
  for (j = 0, len = ref.length; j < len; j++) {
    id = ref[j];
    results.push($("#" + id).show());
  }
  return results;
};

window.challenge_list_setup = function() {
  $("#picker_div").show();
  $("#challenge_div").hide();
  $("#new_challenge_div").hide();
  return $("#result_div").hide();
};

window.announce_result = function() {
  $("#count").html("" + this.count);
  if (this.min_count === 'none') {
    $("#optimal").hide();
    $("#non-optimal").hide();
  } else if (this.count > this.min_count) {
    $("#optimal").hide();
    $("#non-optimal").show();
  } else {
    $("#non-optimal").hide();
    $("#optimal").show();
  }
  $("#challenge_div").hide();
  return $("#result_div").show();
};

window.matrices = {
  'h_scale_2': [2, 0, 0, 1],
  'h_scale_half': [0.5, 0, 0, 1],
  'scale_2': [2, 0, 0, 2],
  'scale_half': [0.5, 0, 0, 0.5],
  'shear_left': [1, -1, 0, 1],
  'shear_right': [1, 1, 0, 1],
  'shear_up': [1, 0, 1, 1],
  'shear_down': [1, 0, -1, 1],
  'reflect_x_axis': [1, 0, 0, -1],
  'rotate_45cc': [1 / Math.sqrt(2), -1 / Math.sqrt(2), 1 / Math.sqrt(2), 1 / Math.sqrt(2)],
  'rotate_45c': [1 / Math.sqrt(2), 1 / Math.sqrt(2), -1 / Math.sqrt(2), 1 / Math.sqrt(2)]
};

window.demo = new Demo2D({
  preload: {
    image: 'img/' + ((ref = urlParams.pic) != null ? ref : "buzz.jpg")
  },
  ortho: ortho,
  camera: {
    position: [1.1, 0, ortho],
    lookAt: [1.1, 0, 0]
  },
  vertical: 2.2
}, function() {
  var axisOpts, challenges, clipCube, fn, fn1, future_matrix, gridOpts, i, id, inverse, j, matrix, numTransforms, ref1, ref2, view1, view2;
  window.mathbox = this.mathbox;
  matrix = [1, 0, 0, 1];
  future_matrix = matrix;
  if (this.urlParams.mat != null) {
    matrix = this.urlParams.mat.split(",").map(parseFloat);
  }
  numTransforms = 3;
  if (this.urlParams.num != null) {
    numTransforms = parseInt(this.urlParams.num);
  }
  inverse = null;
  gridOpts = {
    color: 'white',
    opacity: 0.25,
    width: 1,
    zOrder: 1,
    zIndex: 1
  };
  axisOpts = {
    color: 'white',
    opacity: 0.6,
    zIndex: 1,
    zOrder: 1,
    size: 3
  };
  view1 = this.view({
    name: 'view1',
    gridOpts: gridOpts,
    axisOpts: axisOpts,
    axisLabels: false
  });
  view1.image({
    image: this.image
  }).matrix({
    width: 2,
    height: 2,
    channels: 2,
    data: [[[-10, -10], [10, -10]], [[-10, 10], [10, 10]]]
  }).surface({
    color: 'white',
    points: '<',
    map: '<<',
    fill: true,
    zOrder: 0
  });
  view2 = this.view({
    name: 'view2',
    viewOpts: {
      position: [2.2, 0, 0]
    },
    gridOpts: gridOpts,
    axisOpts: axisOpts,
    axisLabels: false
  });
  clipCube = this.clipCube(view2, {
    draw: false,
    hilite: false,
    range: 10.0,
    pass: 'view'
  });
  clipCube.clipped.transform({}, {
    matrix: function() {
      return [window.matrix[0], window.matrix[1], 0, 0, window.matrix[2], window.matrix[3], 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
    }
  }).image({
    image: this.image
  }).matrix({
    width: 2,
    height: 2,
    channels: 2,
    data: [[[-10, -10], [10, -10]], [[-10, 10], [10, 10]]]
  }).surface({
    id: 'real_image',
    color: 'white',
    points: '<',
    map: '<<',
    fill: true,
    zOrder: 0
  });
  clipCube.clipped.transform({}, {
    matrix: function() {
      return [window.tempmatrix[0], window.tempmatrix[1], 0, 0, window.tempmatrix[2], window.tempmatrix[3], 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
    }
  }).image({
    image: this.image
  }).matrix({
    width: 2,
    height: 2,
    channels: 2,
    data: [[[-10, -10], [10, -10]], [[-10, 10], [10, 10]]]
  }).surface({
    id: 'temp_image',
    color: 'white',
    opacity: 0.5,
    points: '<',
    map: '<<',
    fill: true,
    zOrder: 0,
    visible: false
  });
  this.caption('<div id="picker_div">\n<p id="pick_inst"> Pick a challenge! </p>\n<hr>\n<ul id="challenge_list">\n</ul>\n</div>\n<div id="challenge_div">\n<p id="challenge_inst"> </p>\n<hr>\n<table id="button-table">\n    <tr id="h-shears">\n        <td><button type="button" id="shear_left">Shear left</button></td>\n        <td><button type="button" id="shear_right">Shear right</button></td>\n    </tr>\n    <tr id="v-shears">\n        <td><button type="button" id="shear_up">Shear up</button></td>\n        <td><button type="button" id="shear_down">Shear down</button></td>\n    </tr>\n    <tr id="rotation">\n        <td><button type="button" id="rotate_45cc">Rotate left by 45&deg;</button></td>\n        <td><button type="button" id="rotate_45c">Rotate right by 45&deg;</button></td>\n    </tr>\n    <tr id="scale">\n        <td><button type="button" id="scale_2">Scale by 2</button></td>\n        <td><button type="button" id="scale_half">Scale by 1/2</button></td>\n    </tr>\n    <tr id="h_scale">\n        <td><button type="button" id="h_scale_2">Scale by 2 horizontally</button></td>\n        <td><button type="button" id="h_scale_half">Scale by 1/2 horizontally</button></td>\n    </tr>\n    <tr id="reflect">\n        <td><button type="button" id="reflect_x_axis">Reflect about the x-axis</button></td>\n    </tr>\n</table>\n</div>\n<div id="result_div">\n    <p>Congratulations, you completed the challenge in <span id="count"></span> steps!</p>\n    <p id="non-optimal">That\'s more than the optimal. Try again!</p>\n    <p id="optimal" style="color:green">That\'s the optimal number of moves!</p>\n</div>\n<div id="new_challenge_div">\n    <hr>\n    <button id="new-challenge-btn">Pick another challenge</button>\n</div>');
  challenges = [
    {
      name: "Zoom",
      message: "Transform the figure on the right to the one on the left",
      starting_matrix: [0, 0.25, -0.25, 0],
      winning_matrix: [1, 0, 0, 1],
      transformations: ["rotation", "scale"],
      min_count: 4
    }, {
      name: "Reflect",
      message: "Transform the figure on the right to the one on the left",
      starting_matrix: [0, 1, 1, 0],
      winning_matrix: [1, 0, 0, 1],
      transformations: ["rotation", "reflect"],
      min_count: 3
    }, {
      name: "Scale",
      message: "Transform the figure on the right to the one on the left",
      starting_matrix: [1, 0, 0, 0.25],
      winning_matrix: [1, 0, 0, 1],
      transformations: ["rotation", "h_scale"],
      min_count: 6
    }, {
      name: "Unwind",
      message: 'Transform the distorted figure back to the original figure.',
      starting_matrix: [5, 4, 6, 5],
      winning_matrix: [1, 0, 0, 1],
      transformations: ["h-shears", "v-shears"],
      min_count: 6
    }, {
      name: "Rotate",
      message: 'Rotate the figure back to its original position.',
      starting_matrix: [0, -1, 1, 0],
      winning_matrix: [1, 0, 0, 1],
      transformations: ["h-shears", "v-shears"],
      min_count: 3
    }, {
      name: "Random",
      message: "Transform the figure on the right to the one on the left",
      starting_matrix: 'random',
      winning_matrix: [1, 0, 0, 1],
      transformations: ["rotation", "h-shears", "v-shears", "reflect"],
      min_count: 'none'
    }
  ];
  fn = function() {
    var $ch, $li, ch, ii;
    ii = i;
    ch = challenges[ii - 1];
    $li = $("<li>");
    $ch = $("<button>", {
      id: "ch" + ii
    });
    $ch.click(function() {
      return window.startGame(ch);
    });
    $ch.html(("Challenge " + ii + ": ") + ch.name);
    $li.append($ch);
    return $("#challenge_list").append($li);
  };
  for (i = j = 1, ref1 = challenges.length + 1; 1 <= ref1 ? j < ref1 : j > ref1; i = 1 <= ref1 ? ++j : --j) {
    fn();
  }
  ref2 = window.matrices;
  fn1 = function() {
    var $btn, id2;
    id2 = id;
    $btn = $("#" + id2);
    $btn.click(function() {
      return window.updateMatrix(window.matrices[id2]);
    });
    $btn.mouseover(function() {
      return window.tempUpdateMatrix(window.matrices[id2]);
    });
    return $btn.mouseleave(function() {
      return window.hideTempImage();
    });
  };
  for (id in ref2) {
    matrix = ref2[id];
    fn1();
  }
  $("#new-challenge-btn").click(function() {
    return window.challenge_list_setup();
  });
  return window.challenge_list_setup();
});


        });
    </script>
</body>
</html>

